/*
 * Copyright 2015 <copyright holder> <email>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#pragma once

#include<iostream>
#include <ctime>
#include <thread>
#include <mutex>

#include "es_util.h"

/**
CHECK_RESULT static void print()
{}

template<typename T, typename... Args>
CHECK_RESULT static void print(T t, Args... args)
{
    std::cout<<t;
    print(args...);
}
template<typename T, typename... Args>
CHECK_RESULT static void println(T t, Args... args)
{
    static std::mutex print_buffer_mutex;
    {
      std::lock_guard<std::mutex> gcd(print_buffer_mutex);
      print(esvr::get_current_datetime_str(), " [PRTLN]" , "--", "[t-",  std::this_thread::get_id(), "] ");
      print(t, args...);
      std::cout<<std::endl;
      std::flush(std::cout);
    }
}
*/

namespace esvr
{
    enum LogLevel
    {
        LL_DEBUG,
        LL_INFO,
        LL_WARNING,
        LL_ERROR,
        LL_FATAL,
    };
    CHECK_RESULT static const char * LogLevelStr[]  = {
            "DEBUG",
            "INFOX",
            "WARNI",
            "ERROR",
            "FATAL",
    };

    class Logger
    {
    public: Logger(){} virtual ~Logger(){}

    public:
        virtual void log(LogLevel, const char* fmt, ...)=0;
    };

    extern Logger* g_LoggerInst;
};

#define LOG(level, fmt, ...) esvr::g_LoggerInst->log(level, fmt, ##__VA_ARGS__)
#define LOG_DEBUG(fmt, ...) esvr::g_LoggerInst->log(esvr::LL_DEBUG, fmt, ##__VA_ARGS__)
#define log_debug LOG_DEBUG
#define LOG_INFO(fmt, ...) esvr::g_LoggerInst->log(esvr::LL_INFO, fmt, ##__VA_ARGS__)
#define log_info LOG_INFO
#define LOG_WARNING(fmt, ...) esvr::g_LoggerInst->log(esvr::LL_WARNING, fmt, ##__VA_ARGS__)
#define log_warn LOG_WARNING
#define log_warning LOG_WARNING
#define LOG_ERROR(fmt, ...) esvr::g_LoggerInst->log(esvr::LL_ERROR, fmt, ##__VA_ARGS__)
#define log_error LOG_ERROR
#define LOG_FATAL(fmt, ...) esvr::g_LoggerInst->log(esvr::LL_FATAL, fmt, ##__VA_ARGS__)
#define log_fatal LOG_FATAL
